package be.novelfaces.component.input;

import javax.faces.component.UIInput;
import javax.faces.component.behavior.ClientBehaviorHolder;

import org.richfaces.cdk.annotations.Attribute;
import org.richfaces.cdk.annotations.Description;
import org.richfaces.cdk.annotations.EventName;
import org.richfaces.cdk.annotations.JsfComponent;
import org.richfaces.cdk.annotations.JsfRenderer;
import org.richfaces.cdk.annotations.Tag;
import org.richfaces.cdk.annotations.TagType;

import be.novelfaces.component.properties.FormEventProperties;
import be.novelfaces.component.properties.GlobalProperties;
import be.novelfaces.component.properties.KeyboardEventProperties;
import be.novelfaces.component.properties.MouseEventProperties;

@JsfComponent(tag = @Tag(type = TagType.Facelets, name = "inputText"), //
type = AbstractInputText.COMPONENT_TYPE, //
family = AbstractInputText.COMPONENT_FAMILY, //
generate = "be.novelfaces.component.input.InputText", //
renderer = @JsfRenderer(type = AbstractInputText.DEFAULT_RENDERER))
public abstract class AbstractInputText extends UIInput implements
		ClientBehaviorHolder, KeyboardEventProperties, GlobalProperties,
		MouseEventProperties, FormEventProperties {

	public static final String COMPONENT_TYPE = "be.novelfaces.component.InputText";
	public static final String COMPONENT_FAMILY = "be.novelfaces.component";
	public static final String DEFAULT_RENDERER = "be.novelfaces.component.InputTextRenderer";

	@Attribute(description = @Description(value = "A localized user presentable name for this component.", //
	displayName = "label"))
	public abstract String getLabel();

	@Attribute(description = @Description(value = "<p>The autocomplete attribute specifies whether or not the the input field should have autocomplete enabled.</p>" //
			+ "<p>Autocomplete allows the browser to predict the input for a field. " //
			+ "When the user starts to type in a field, the browser should display options to fill in the field, based on earlier typed values.</p>" //
			+ "<p>Possible values are:</p>" //
			+ "<ul>" //
			+ "<li>on - Default. Specifies that autocomplete is enabled</li>" //
			+ "<li>off - Specifies that autocomplete is disabled</li>" //
			+ "</ul>", //
	displayName = "autocomplete"))
	public abstract String getAutocomplete();

	@Attribute(description = @Description(value = "The autofocus attribute specifies that the input element should automatically get focus when a page is loaded. " //
			+ "A value of false causes no attribute to be rendered, while a value of true causes the attribute to be rendered as autofocus=\"autofocus\".", //
	displayName = "autofocus"))
	public abstract boolean isAutofocus();

	@Attribute(description = @Description(value = "<p>The disabled attribute specifies that an input element should be disabled. " //
			+ "A disabled input element is unusable and un-clickable. </p>" //
			+ "<p>The disabled attribute can be set to keep a user from using an input element until some other condition has been met (like selecting a checkbox, etc.). " //
			+ "Then, a JavaScript is required to remove the disabled value, and make the input element usable.</p>" //
			+ "<p>A value of false causes no attribute to be rendered, while a value of true causes the attribute to be rendered as disabled=\"disabled\".</p>" //
			+ " <em>Tip</em>: Disabled form elements will not be submitted.", //
	displayName = "disabled"))
	public abstract boolean isDisabled();

	@Attribute(description = @Description(value = "<p>The form attribute specifies one or more forms the input element belongs to.</p>" //
			+ "<p>The value of the form attribute must be the id of the form it belongs to.</p>" //
			+ "<p>To refer to more than one form, use a space-separated list.</p>", //
	displayName = "form"))
	public abstract String getForm();

	@Attribute(description = @Description(value = "<p>The list attribute refers to a datalist containing predefined options for the " //
			+ "input field (see http://www.w3schools.com/html5/tag_datalist.asp for more details).</p>", //
	displayName = "list"))
	public abstract String getList();

	@Attribute(description = @Description(value = "The maximum number of characters that may be entered in this field.", //
	displayName = "maxlength"))
	public abstract int getMaxlength();

	@Attribute(description = @Description(value = "The pattern attribute specifies a pattern used to validate an input field. The pattern is a regular expression.", //
	displayName = "pattern"))
	public abstract String getPattern();

	@Attribute(description = @Description(value = "Specifies a hint to help users fill out the input field.", //
	displayName = "placeholder"))
	public abstract String getPlaceholder();

	@Attribute(description = @Description(value = "<p>The readonly attribute specifies that an input field should be read-only.</p>" //
			+ "<p>A read-only field cannot be modified. However, a user can tab to it, highlight it, and copy the text from it.</p>" //
			+ "<p>If this attribute is present the field will be read-only.</p>" //
			+ "<p>A value of false causes no attribute to be rendered, while a value of true causes the attribute to be rendered as readonly=\"readonly\".</p>" //
			+ "<em>Note:</em> Read-only input fields will not be validated.", //
	displayName = "readonly"))
	public abstract boolean isReadonly();

	@Attribute(description = @Description(value = "<p>The required attribute specifies that an input field must be filled out before submitting.</p>" //
			+ "<p>If this attribute is present the field will required. A value of false causes no attribute to be rendered, while a value of true causes the " //
			+ "attribute to be rendered as required=\"required\".</p>", //
	displayName = "required"))
	public abstract boolean isRequired();

	@Attribute(description = @Description(value = "The number of characters used to determine the width of this field.", //
	displayName = "size"))
	public abstract int getSize();
	
	@Attribute(description = @Description(value = "Script to be run when an element changes.", //
			displayName = "onchange"), //
			events = { @EventName(value = "valueChange", defaultEvent = true),
					@EventName("onchange") })
	public abstract String getOnchange();

}
